package weibo4j;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import weibo4j.http.Response;
import weibo4j.org.json.JSONArray;
import weibo4j.org.json.JSONException;
import weibo4j.org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A data class representing one single status of a user.
 * @author Yusuke Yamamoto - yusuke at mac.com
 */
public class Comment extends WeiboResponse implements java.io.Serializable {

    private Date createdAt;
    private long id;
    private String text;
    private User user = null;
    private Status status = null;
    private static final long serialVersionUID = 1608000492860584608L;

    /*package*/Comment(Response res, Weibo weibo) throws WeiboException {
        super(res);
        Element elem = res.asDocument().getDocumentElement();
        init(res, elem, weibo);
    }
    
    /*modify by sycheng add json define */
    /*package*/Comment(Response res) throws WeiboException {
        super(res);
        JSONObject json =res.asJSONObject();
        try {
			id = json.getLong("id");
			text = json.getString("text");
			createdAt = parseDate(json.getString("created_at"), "EEE MMM dd HH:mm:ss z yyyy");

			if(!json.isNull("user"))
				user = new User(json.getJSONObject("user"));
			if(!json.isNull("status"))
				status = new Status(json.getJSONObject("status"));
		} catch (JSONException je) {
			throw new WeiboException(je.getMessage() + ":" + json.toString(), je);
		}
    }
    
    /* modify by hezhou add some field*/
    public Comment(JSONObject json)throws WeiboException, JSONException{
    	id = json.getLong("id");
		text = json.getString("text");
		createdAt = parseDate(json.getString("created_at"), "EEE MMM dd HH:mm:ss z yyyy");		
		
		if(!json.isNull("user"))
			user = new User(json.getJSONObject("user"));
		if(!json.isNull("status"))
			status = new Status(json.getJSONObject("status"));
    }

    /*package*/Comment(Response res, Element elem, Weibo weibo) throws
            WeiboException {
        super(res);
        init(res, elem, weibo);
    }

    public Comment(String str) throws WeiboException, JSONException {
        // StatusStream uses this constructor
        super();
        JSONObject json = new JSONObject(str);
        id = json.getLong("id");
        text = json.getString("text");
        createdAt = parseDate(json.getString("created_at"), "EEE MMM dd HH:mm:ss z yyyy");

        user = new User(json.getJSONObject("user"));
        status = new Status(json.getJSONObject("status"));
    }

    private void init(Response res, Element elem, Weibo weibo) throws
            WeiboException {
        ensureRootNodeNameIs("comment", elem);
        user = new User(res, (Element) elem.getElementsByTagName("user").item(0)
                , weibo);
        id = getChildLong("id", elem);
        text = getChildText("text", elem);
        createdAt = getChildDate("created_at", elem);
        NodeList users = elem.getElementsByTagName("user");
		if (users.getLength() != 0) {
			Element userContent = (Element) users.item(0);
			user = new User(userContent);
		}
        NodeList statuses = elem.getElementsByTagName("status");
		if (statuses.getLength() != 0) {
			Element statusContent = (Element) statuses.item(0);
			status = new Status(statusContent);
		}
    }

    /**
     * Return the created_at
     *
     * @return created_at
     * @since Weibo4J 1.1.0
     */

    public Date getCreatedAt() {
        return this.createdAt;
    }

    /**
     * Returns the id of the status
     *
     * @return the id
     */
    public long getId() {
        return this.id;
    }

    /**
     * Returns the text of the status
     *
     * @return the text
     */
    public String getText() {
        return this.text;
    }

    /**
     * Return the user
     *
     * @return the user
     */
    public User getUser() {
        return user;
    }
    
    public boolean isUserEmpty(){
    	return null != user;
    }
    
    public long getUserId(){
    	return user.getId();
    }

    /**
     *
     * @since Weibo4J 2.0.10
     */
    public boolean isCommentedStatusEmpty(){
        return null != status;
    }
    
    public long getCommentedStatusId(){
    	return status.getId();
    }   

    /**
     *
     * @since Weibo4J 2.0.10
     */
    public Status getCommentdStatus() {
        return status;
    }


    /*package*/
    static List<Comment> constructStatuses(Response res,
                                          Weibo weibo) throws WeiboException {
        Document doc = res.asDocument();
        if (isRootNodeNilClasses(doc)) {
            return new ArrayList<Comment>(0);
        } else {
            try {
                ensureRootNodeNameIs("statuses", doc);
                NodeList list = doc.getDocumentElement().getElementsByTagName(
                        "status");
                int size = list.getLength();
                List<Comment> statuses = new ArrayList<Comment>(size);
                for (int i = 0; i < size; i++) {
                    Element status = (Element) list.item(i);
                    statuses.add(new Comment(res, status, weibo));
                }
                return statuses;
            } catch (WeiboException te) {
                ensureRootNodeNameIs("nil-classes", doc);
                return new ArrayList<Comment>(0);
            }
        }
    }
    
    /* modify by hezhou add some field*/
    static List<Comment> constructComments(Response res) throws WeiboException {
   	 try {
            JSONArray list = res.asJSONArray();
            int size = list.length();
            List<Comment> comments = new ArrayList<Comment>(size);
            for (int i = 0; i < size; i++) {
            	comments.add(new Comment(list.getJSONObject(i)));
            }
            return comments;
        } catch (JSONException jsone) {
            throw new WeiboException(jsone);
        } catch (WeiboException te) {
            throw te;
        }  
      
   }

    @Override
    public int hashCode() {
        return (int) id;
    }

    @Override
    public boolean equals(Object obj) {
        if (null == obj) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        return obj instanceof Comment && ((Comment) obj).id == this.id;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "createdAt=" + createdAt +
                ", id=" + id +
                ", text='" + text + '\'' +
                ", commentedStatus=" + status.toString() +
                ", user=" + user.toString() +
                '}';
    }
    
    public String getCommentSQLString(String encoding) throws UnsupportedEncodingException {
        return "insert into comments set created_at='" + myFormat.format(createdAt) + '\'' +
                ", comment_id=" + id +
                ", text='" + URLEncoder.encode(text, encoding) + '\'' +
                ", commented_status_id=" + (isCommentedStatusEmpty() ? 0 : getCommentedStatusId() ) +
                ", user_id=" + (isUserEmpty() ? 0 : user.getId());
    }
    public String getCommentSQLString(String table, String encoding) throws UnsupportedEncodingException {
        return "insert into " + table + " set created_at='" + myFormat.format(createdAt) + '\'' +
                ", comment_id=" + id +
                ", text='" + URLEncoder.encode(text, encoding) + '\'' +
                ", commented_status_id=" + (isCommentedStatusEmpty() ? 0 : getCommentedStatusId() ) +
                ", user_id=" + (isUserEmpty() ? 0 : user.getId());
    }
    
    public Map<String, String> getRecordMap(String encoding) throws UnsupportedEncodingException {
    	Map<String, String> res = new HashMap<String, String>();
        res.put("created_at",  '\'' + myFormat.format(createdAt) + '\'');
        res.put("id", Long.toString(id));
        res.put("text", '\'' + URLEncoder.encode(text, encoding) + '\'');
        res.put("commented_status_id", Long.toString(isCommentedStatusEmpty() ? 0 : getCommentedStatusId()));
        res.put("user_id", Long.toString(isUserEmpty() ? 0 : user.getId()));
        return res;
    }
    
    public static String getFiledString(){
    	return "( created_at, comment_id, text, commented_status_id, user_id)";
    }
    
    public static String getEmptyValueString(){
    	return "( ?, ?, ?, ?, ?)";
    }
    
    public String[] getRecord(String encoding) throws UnsupportedEncodingException{
    	String[] res = new String[5];
    	res[0] = myFormat.format(createdAt);
    	res[1] = Long.toString(id);
    	res[2] = URLEncoder.encode(text, encoding);
    	res[3] = Long.toString(isCommentedStatusEmpty() ? 0 : getCommentedStatusId());
    	res[4] = Long.toString(isUserEmpty() ? 0 : user.getId());
		return res;
    	
    }
    
    
}
